<template>
  <div class="streaming-chat-container">
    <!-- 聊天区域 -->
    <div class="chat-messages" ref="messagesContainer">
      <!-- 系统消息 -->
      <div class="message system" v-if="systemMessage">
        <div class="message-content">{{ systemMessage }}</div>
      </div>

      <!-- 历史消息 -->
      <div
          class="message"
          :class="{ 'user': message.role === 'user', 'assistant': message.role === 'assistant' }"
          v-for="(message, index) in messages"
          :key="index"
      >
        <div class="message-avatar">
          <img
              :src="message.role === 'user' ? userAvatar : assistantAvatar"
              alt="Avatar"
          >
        </div>
        <div class="message-content">
          <div class="message-text" v-html="message.content"></div>
        </div>
      </div>

      <!-- 正在输入动画 -->
      <div class="message assistant typing-indicator" v-if="isLoading">
        <div class="message-avatar">
          <img src="https://picsum.photos/200/200?random=assistant" alt="Assistant Avatar">
        </div>
        <div class="message-content">
          <div class="message-text">
            <span class="typing-dot"></span>
            <span class="typing-dot"></span>
            <span class="typing-dot"></span>
          </div>
        </div>
      </div>
    </div>

    <!-- 输入区域 -->
    <div class="chat-input">
      <el-input
          v-model="inputText"
          placeholder="请输入问题..."
          @keyup.enter="sendMessage"
          :disabled="isLoading"
          ref="inputRef"
      ></el-input>
      <el-button
          @click="sendMessage"
          :disabled="!inputText.trim() || isLoading"
      >
        发送
      </el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import {userTokenStore} from "@/store/userTokenStore.js";

// 状态管理
const inputRef = ref(null);
const messagesContainer = ref(null);
const inputText = ref('');
const isLoading = ref(false);
const systemMessage = ref('');
const assistantAvatar = 'https://picsum.photos/200/200?random=assistant';
const userAvatar = 'https://picsum.photos/200/200?random=user';

// 消息历史
const messages = reactive([]);
const token = userTokenStore().token;
// 连接流式API
const streamResponse = async (query) => {
  try {
    isLoading.value = true;

    // 添加用户消息到历史
    messages.push({
      role: 'user',
      content: query,
      timestamp: new Date().toISOString()
    });

    // 添加空的助手消息用于流式更新
    const assistantMessageIndex = messages.length;
    messages.push({
      role: 'assistant',
      content: '',
      timestamp: new Date().toISOString()
    });

    // 自动滚动到底部
    scrollToBottom();

    // 调用后端流式API
    const response = await fetch('/api/ai/embeddings/query', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': token
      },
      body: JSON.stringify({ query }),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    // 处理流式响应
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let fullResponse = '';

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      // 解码接收到的数据
      const chunk = decoder.decode(value, { stream: true });
      fullResponse += chunk;

      // 更新UI
      messages[assistantMessageIndex].content = fullResponse;

      // 处理特殊情况：如果是HTML内容，转义特殊字符
      if (chunk.includes('<') || chunk.includes('>')) {
        messages[assistantMessageIndex].content = fullResponse.replace(/</g, '&lt;').replace(/>/g, '&gt;');
      }

      // 每次更新后滚动到底部
      await nextTick();
      scrollToBottom();
    }

    // 处理完成后的格式化
    messages[assistantMessageIndex].content = fullResponse;

    // 重置输入框
    inputText.value = '';
    await nextTick();
    inputRef.value.focus();

  } catch (error) {
    console.error('Error streaming response:', error);
    ElMessage.error('获取响应时出错，请重试');
  } finally {
    isLoading.value = false;
  }
};

// 发送消息
const sendMessage = () => {
  const query = inputText.value.trim();
  if (!query) return;

  streamResponse(query);
};

// 滚动到消息底部
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    }
  });
};

// 初始化
onMounted(() => {
  systemMessage.value = '欢迎使用专业教学助手，请问有什么可以帮助您的？';
  scrollToBottom();
  inputRef.value.focus();
});
</script>

<style scoped>
.streaming-chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #f9fafc;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.chat-input {
  display: flex;
  gap: 8px;
  padding: 16px;
  border-top: 1px solid #e4e7ed;
}

.message {
  display: flex;
  gap: 12px;
  animation: fadeIn 0.3s ease-out;
}

.message.system {
  justify-content: center;
  margin-bottom: 12px;
}

.message.system .message-content {
  background-color: #f0f2f5;
  color: #606266;
  padding: 8px 16px;
  border-radius: 16px;
  font-size: 14px;
  max-width: 80%;
  text-align: center;
}

.message.user {
  justify-content: flex-end;
}

.message.assistant {
  justify-content: flex-start;
}

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
}

.message-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.message-content {
  max-width: 80%;
  padding: 12px 16px;
  border-radius: 18px;
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.message.user .message-content {
  background-color: #409eff;
  color: white;
}

.message.assistant .message-content {
  background-color: white;
  color: #303133;
  border: 1px solid #e4e7ed;
}

.typing-indicator .message-text {
  display: flex;
  gap: 3px;
}

.typing-dot {
  width: 6px;
  height: 6px;
  background-color: #909399;
  border-radius: 50%;
  animation: typing 1.4s infinite both;
}

.typing-dot:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
  100% { transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}
</style>
